module usb_uart (	
      input  wire  REFCLK,
	   input  wire  RX,
		output reg   TX     
   );

// Assumption:
//   + Oversampling rate is power of 2.
//   + PLL provides close enough clock
//   + Only support 8N1 format.
//


   
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Instantiate own PLL of UART rate
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wire uart_pll_clk;
uart_pll uart_pll_inst (
		.refclk    (REFCLK),                 //  refclk.clk
		.rst       (1'b0),                   //   reset.reset
		.outclk_0  (uart_pll_clk),   // outclk0.clk
		.outclk_1  (),                       // outclk0.clk
		.locked    ()                        //  locked.export
	);

   
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Synchronize RX to system clk
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
reg  r_RX, r_RX_0;
always @(posedge uart_pll_clk )
begin
  r_RX_0 <= RX;
  r_RX   <= r_RX_0;
end


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Sampling counter
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

localparam COUNTER_OVERSAMPLE = 3;               // Sample (2^COUNTER_OVERSAMPLE) per bit
localparam COUNTER_LEN = COUNTER_OVERSAMPLE + 4; // Counter length to count (2^COUNTER_OVERSAMPLE)/bits x 10bits,
                                                 // 10 bits = 1 transfer byte of (1start+8data+1stop)

reg         [COUNTER_LEN-1:0] r_counter;     // Counter increments on sampling clk during baud time
reg  [COUNTER_OVERSAMPLE-1:0] r_bitsum;      // Cumulative samples of single bit

reg                           r_byte_active; // Asserts on falling edge of RX at start of startbit, and
                                             // stay asserted until start of stopbit
                                            
reg                     [7:0] r_rxbyte;      // Received byte

wire [COUNTER_OVERSAMPLE-1:0] w_bitsample;
wire                    [3:0] w_bitcnt;
wire                          w_isstopbit;   
wire   w_byte_active;


assign w_bitsample    = r_counter[COUNTER_OVERSAMPLE-1:0];
assign w_bitcnt       = r_counter[COUNTER_LEN-1:COUNTER_OVERSAMPLE];

assign w_isnotstopbit = |(w_bitcnt ^ 4'd9);   // bit 9 (10th) is stopbit.
assign w_isnotzero    = |(w_bitcnt);          
assign w_byte_active  = ( (~r_RX) | (w_isnotstopbit & w_isnotzero) ) ? 1'b1 : 1'b0;   

wire       w_bitedge;  // falling edge of previous bit is bit boundary
assign     w_bitedge   = r_counter[COUNTER_OVERSAMPLE-1];


always @(posedge uart_pll_clk )
begin    
		
      // count only when r_byte_active asserts
      r_counter    <=  (w_byte_active) ? (r_counter+1) : 0; //COUNTER_LEN'd0;

      // Accumulates samples of RX during 1 bit time, resets at start of bit time (w_bitsample!=0).
      r_bitsum     <= (|w_bitsample) ? (r_bitsum+r_RX) : r_RX;    
		
		// Received data:
		r_rxbyte     <= (&w_bitsample) ? { r_bitsum[2], r_rxbyte[7:1] } : r_rxbyte;  // If 4 of 8 samples are 1's, it's a 1!

		TX <= (&w_bitsample) ? &r_rxbyte : TX ;
end


endmodule